package edu.scut.course_management.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.print.DocFlavor.STRING;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import edu.scut.course_management.dao.StudentMapper;
import edu.scut.course_management.dto.RequestStudentDTO;
import edu.scut.course_management.dto.RequestTeacherDTO;
import edu.scut.course_management.exception.CustomException;
import edu.scut.course_management.po.Student;
import edu.scut.course_management.po.Teacher;
import edu.scut.course_management.result.JsonResult;
import edu.scut.course_management.result.JsonResultFactory;
import edu.scut.course_management.result.ResultCode;
import edu.scut.course_management.service.PersonManagementService;
import edu.scut.course_management.util.ParamCheckingUtil;

/**
 * 用户管理模块
 * @author sherry
 */

 @RestController
 @RequestMapping("/Personnel")
public class PersonManagementController {

    @Autowired 
    PersonManagementService personManagementService;
   
    /**
     * 修改个人密码
     * 需要验证是否为用户本人
     */
    @PostMapping("/ModifiedPassword")
    public JsonResult modifiedPassword(@RequestBody Map<String, String> params, Authentication authentication){

        JsonResult result = null;
        Object currentUser = authentication.getPrincipal();

        if (currentUser instanceof Student) {
            String studentId = ((Student) currentUser).getStudentId();
            if (!ParamCheckingUtil.paramsNotNull(params, "id", "oldPassword", "newPassword")) {
                result = JsonResultFactory.getInstance().buildFailResult(ResultCode.PARAM_NOT_COMPLETE);
            } 
            else if (!(params.get("id").equals(studentId))) {
                result = JsonResultFactory.getInstance().buildFailResult(ResultCode.PARAM_ERROR, "传入的学号与当前登录的学号不一致");
            } 
            else if (!ParamCheckingUtil.paramsNotEmpty(params, "oldPassword", "newPassword")) {
                result = JsonResultFactory.getInstance().buildFailResult(ResultCode.PARAM_ERROR, "密码不能全为空格，或者为空");
            } 
            else {
                try {
                    personManagementService.modifiedStudentPassword(studentId, params.get("oldPassword").trim(), params.get("newPassword").trim());
                    result = JsonResultFactory.getInstance().buildSuccessResult();
                } catch (CustomException e) {
                    result = JsonResultFactory.getInstance().buildFailResult(e.getResultCode());
                }
            }
        }
        else {
            String teacherId = ((Teacher) currentUser).getTeacherId();
            if (!ParamCheckingUtil.paramsNotNull(params, "id", "oldPassword", "newPassword")) {
                result = JsonResultFactory.getInstance().buildFailResult(ResultCode.PARAM_NOT_COMPLETE);
            } 
            else if (!(params.get("id").equals(teacherId))) {
                result = JsonResultFactory.getInstance().buildFailResult(ResultCode.PARAM_ERROR, "传入的工号与当前登录的工号不一致");
            } 
            else if (!ParamCheckingUtil.paramsNotEmpty(params, "oldPassword", "newPassword")) {
                result = JsonResultFactory.getInstance().buildFailResult(ResultCode.PARAM_ERROR, "密码不能全为空格，或者为空");
            } 
            else {
                try {
                    personManagementService.modifiedTeacherPassword(teacherId, params.get("oldPassword").trim(), params.get("newPassword").trim());
                    result = JsonResultFactory.getInstance().buildSuccessResult();
                } catch (CustomException e) {
                    result = JsonResultFactory.getInstance().buildFailResult(e.getResultCode());
                }
            }
        }
        return result;

    }

    /**
     * 重置用户密码
     */
    @PostMapping("/ResetPassword")
    public JsonResult resetPassword(@RequestBody Map<String, String> params) {
        JsonResult result = null;
        JsonResultFactory jsonResultFactory = JsonResultFactory.getInstance();
        String userId = params.get("userId");
        if (personManagementService.isExistStudentAccount(userId)) {
            try {
                personManagementService.resetStudentPassword(userId);
                result = jsonResultFactory.buildSuccessResult("重置密码成功，密码为账号");
            } catch (CustomException e) {
                result = jsonResultFactory.buildFailResult(e.getResultCode());
            }
        } else if (personManagementService.isExistTeacherAccount(userId)) {
            try {
                personManagementService.resetTeacherPassword(userId);
                result = jsonResultFactory.buildSuccessResult("重置密码成功，密码为账号");
            } catch (CustomException e) {
                result = jsonResultFactory.buildFailResult(e.getResultCode());
            }
        } else {
            result = jsonResultFactory.buildFailResult(ResultCode.USER_ACCOUNT_NOT_EXIST);
        }

        return result;
    }


    /**
     * 更新学生的个人信息
     * 需要验证是否为本人
     */
    @PostMapping("/Student/UpdateInfo")
    public JsonResult updateStudentInfo(@RequestBody Map<String, String> params, Authentication authentication) {

        JsonResult result = null;
        JsonResultFactory jsonResultFactory = JsonResultFactory.getInstance();
        Object currentUser = authentication.getPrincipal();

        if (currentUser instanceof Student) {
            String studentId = ((Student) currentUser).getStudentId();

            if (!ParamCheckingUtil.paramsNotNull(params, "studentId", "phoneNumber", "address")) {
                result = jsonResultFactory.buildFailResult(ResultCode.PARAM_NOT_COMPLETE);
            } 
            else if (!(params.get("studentId").equals(studentId))) {
                result = jsonResultFactory.buildFailResult(ResultCode.PARAM_ERROR, "传入的学号与当前登录的学号不一致");
            } 
            else {
                Student student = personManagementService.findStudentById(studentId);
                student.setPhoneNumber(params.get("phoneNumber"));
                student.setAddress(params.get("address"));
                try {
                    personManagementService.modifiedStudent(student);
                    result = jsonResultFactory.buildSuccessResult("修改学生信息成功");
                } catch (CustomException e) {
                    result = jsonResultFactory.buildFailResult(e.getResultCode());
                }
            } 
        } else {
            result = JsonResultFactory.getInstance().buildFailResult(ResultCode.NO_PERMISSION);
        }
        return result;

    }

    /**
     * 修改学生的个人信息
     * 需要管理员权限
     */
    @PostMapping("/Student/ModifiedInfo")
    @PreAuthorize("hasAuthority('admin')")
    public JsonResult modifiedStudentInfo(@RequestBody Map<String, Object> params) {

        JsonResult result = null;
        JsonResultFactory jsonResultFactory = JsonResultFactory.getInstance();

        String studentId = (String) params.get("studentId");
        String[] requiredParam = {"studentId", "name", "male", "majorId", "enrollmentYear",
                "className", "phoneNumber", "address"};
        
        if (!ParamCheckingUtil.paramsNotNull(params, requiredParam)) {
            result = jsonResultFactory.buildFailResult(ResultCode.PARAM_NOT_COMPLETE);
        }
        else if (!ParamCheckingUtil.paramsNotEmpty(params, "studentId", "name")) {
            result = jsonResultFactory.buildFailResult(ResultCode.PARAM_NOT_COMPLETE, "学号或姓名为空");
            } 
        else if (!personManagementService.isExistStudentAccount(studentId)) {
            result = jsonResultFactory.buildFailResult(ResultCode.USER_ACCOUNT_NOT_EXIST);
        } 
        else {
            Student student = personManagementService.findStudentById(studentId);
            student.setName((String) params.get("name"));
            student.setMale((boolean) params.get("male"));
            student.setMajorId((Integer) params.get("majorId"));
            student.setEnrollmentYear((String) params.get("enrollmentYear"));
            student.setClassName((String) params.get("className"));
            student.setPhoneNumber((String) params.get("phoneNumber"));
            student.setAddress((String) params.get("address"));
            try {
                personManagementService.modifiedStudent(student);
                result = jsonResultFactory.buildSuccessResult("修改学生信息成功");
            } catch (CustomException e) {
                result = jsonResultFactory.buildFailResult(e.getResultCode());
            }
        }
        
        return result;

    }

    /**
     * 查询学生的个人信息
     * 需要管理员权限
     */
    @PostMapping("/Student/SearchInfo")
    public JsonResult searchStudentInfo(@RequestBody RequestStudentDTO requestStudentDTO) {

        JsonResult result = null;
        if (requestStudentDTO.checkParamValidity(false)) {
            Map<String, Object> conditions = requestStudentDTO.queryStudent();
            //获得符合条件的学生列表
            Stream<RequestStudentDTO> queryResultStream = personManagementService.searchStudent(conditions).parallelStream();
            Function<RequestStudentDTO, Map<String, Object>> mapFunction = student -> {
                boolean male = student.isMale();
                Integer departmentId = student.getDepartmentId();
                Integer majorId = student.getMajorId();
                
                Map<String, Object> info = new HashMap<>();
                info.put("studentId", student.getStudentId());
                info.put("name", student.getName());
                info.put("male", male ? "男" : "女");
                info.put("departmentId", student.getDepartmentId());
                info.put("departmentName", personManagementService.findDepartmentById(departmentId));
                info.put("majorId", student.getMajorId());
                info.put("majorName", personManagementService.findMajorById(majorId));
                info.put("enrollmentYear", student.getEnrollmentYear());
                info.put("className", student.getClassName());
                info.put("phoneNumber", student.getPhoneNumber());
                info.put("address", student.getAddress());
                return info;
            };
            List<Map<String, Object>> queryResult = queryResultStream.map(mapFunction).collect(Collectors.toList());
            result = JsonResultFactory.getInstance().buildSuccessResult(queryResult);
        }
        else {
            result = JsonResultFactory.getInstance().buildFailResult(ResultCode.PARAM_FORMAT_ERROR);
        }
        return result;

    }

    /**
     * 新增学生的个人信息,学生用户学号需要12位
     * 需要管理员权限
     */
    @PostMapping("/Student/AddInfo")
    @PreAuthorize("hasAuthority('admin')")
    public JsonResult addStudentInfo(@RequestBody RequestStudentDTO requestStudentDTO) {

        JsonResult result = null;
        
        if (!requestStudentDTO.checkParamValidity(true)) {
            result = JsonResultFactory.getInstance().buildFailResult(ResultCode.PARAM_FORMAT_ERROR);
        } 
        else {
            // 默认密码是和学号相同
            Student newStudent =  requestStudentDTO.toObjectStudent();
            newStudent.setPassword(new BCryptPasswordEncoder().encode(newStudent.getStudentId()));
            try {
                personManagementService.addStudentInfo(newStudent);
                result = JsonResultFactory.getInstance().buildSuccessResult("人员信息添加成功，默认密码与学号相同。");
            } catch (CustomException e) {
                result = JsonResultFactory.getInstance().buildFailResult(e.getResultCode());
            }
        } 
        
        return result;

    }

    /**
     * 删除学生的个人信息
     * 需要管理员权限
     */
    @PostMapping("/Student/DeleteInfo")
    @PreAuthorize("hasAuthority('admin')")
    public JsonResult deleteStudentInfo(@RequestBody Map<String, String> params) {

        JsonResult result = null;
        JsonResultFactory jsonResultFactory = JsonResultFactory.getInstance();

        if(!ParamCheckingUtil.paramsNotEmpty(params, "studentId")) {
            result = jsonResultFactory.buildFailResult(ResultCode.PARAM_NOT_COMPLETE);
        }
        else if (!ParamCheckingUtil.paramsNotEmpty(params, "studentId")) {
            result = jsonResultFactory.buildFailResult(ResultCode.PARAM_IS_BLANK, "学号为空");
        } 
        else {
            try {
                personManagementService.deleteStudent(params.get("studentId"));
                result = jsonResultFactory.buildSuccessResult();
            }
            catch (CustomException e) {
                result = jsonResultFactory.buildFailResult(e.getResultCode());
            }
        }
        return result;

    }

    /**
     * 更新教师的个人信息
     * 需要验证是否为本人
     */
    @PostMapping("/Teacher/UpdateInfo")
    public JsonResult updateTeacherInfo(@RequestBody Map<String, String> params, Authentication authentication) {

        JsonResult result = null;
        JsonResultFactory jsonResultFactory = JsonResultFactory.getInstance();
        Object currentUser = authentication.getPrincipal();

        if (currentUser instanceof Teacher) {
            String teacherId = ((Teacher) currentUser).getTeacherId();

            if (!ParamCheckingUtil.paramsNotNull(params, "teacherId", "phoneNumber")) {
                result = jsonResultFactory.buildFailResult(ResultCode.PARAM_NOT_COMPLETE);
            } 
            else if (!(params.get("teacherId").equals(teacherId))) {
                result = jsonResultFactory.buildFailResult(ResultCode.PARAM_ERROR, "传入的工号与当前登录的工号不一致");
            } 
            else {
                Teacher teacher = personManagementService.findTeacherById(teacherId);
                teacher.setPhoneNumber(params.get("phoneNumber"));
                try {
                    personManagementService.modifiedTeacher(teacher);
                    result = jsonResultFactory.buildSuccessResult("修改教师信息成功");
                } catch (CustomException e) {
                    result = jsonResultFactory.buildFailResult(e.getResultCode());
                }
            } 
        } else {
            result = JsonResultFactory.getInstance().buildFailResult(ResultCode.NO_PERMISSION);
        }
        return result;

    }

    /**
     * 修改教师的个人信息
     * 需要管理员权限
     */
    @PostMapping("/Teacher/ModifiedInfo")
    @PreAuthorize("hasAuthority('admin')")
    public JsonResult modifiedTeacherInfo(@RequestBody Map<String, Object> params) {

        JsonResult result = null;
        JsonResultFactory jsonResultFactory = JsonResultFactory.getInstance();

        String teacherId = (String) params.get("teacherId");
        String[] requiredParam = {"teacherId", "name", "male", 
                "phoneNumber", "departmentId", "academicTitle"};
        
        if (!ParamCheckingUtil.paramsNotNull(params, requiredParam)) {
            result = jsonResultFactory.buildFailResult(ResultCode.PARAM_NOT_COMPLETE);
        }
        else if (!ParamCheckingUtil.paramsNotEmpty(params, "teacherId", "name")) {
            result = jsonResultFactory.buildFailResult(ResultCode.PARAM_NOT_COMPLETE, "学号或姓名为空");
        } 
        else if (!personManagementService.isExistTeacherAccount(teacherId)) {
            result = jsonResultFactory.buildFailResult(ResultCode.USER_ACCOUNT_NOT_EXIST);
        } 
        else {
            Teacher teacher = personManagementService.findTeacherById(teacherId);
            teacher.setName((String) params.get("name"));
            teacher.setPhoneNumber((String) params.get("phoneNumber"));
            teacher.setDepartmentId((Integer) params.get("DepartmentId"));
            teacher.setAcademicTitle((String) params.get("academicTitle"));
            teacher.setMale((boolean) params.get("male"));
            try {
                personManagementService.modifiedTeacher(teacher);
                result = jsonResultFactory.buildSuccessResult("修改教师信息成功");
            } catch (CustomException e) {
                result = jsonResultFactory.buildFailResult(e.getResultCode());
            }
        }
        return result;
    }

    /**
     * 查询教师的个人信息
     * 需要管理员权限
     */
    @PostMapping("/Teacher/SearchInfo")
    public JsonResult searchTeacherInfo(@RequestBody RequestTeacherDTO requestTeacherDTO) {

        JsonResult result = null;
        if (requestTeacherDTO.checkParamValidity(false)) {
            Map<String, Object> conditions = requestTeacherDTO.queryTeacher ();
            // 获得符合条件教师列表
            Stream<Teacher> queryResultStream = personManagementService.searchTeacher(conditions).parallelStream();
            Function<Teacher, Map<String, Object>> mapFunction = teacher -> {
                boolean male = teacher.isMale();
                Integer departmentId = teacher.getDepartmentId();
                
                Map<String, Object> info = new HashMap<>();
                info.put("teacherId", teacher.getTeacherId());
                info.put("name", teacher.getName());
                info.put("male", male ? "男" : "女");
                info.put("departmentId", teacher.getDepartmentId());
                info.put("departmentName", personManagementService.findDepartmentById(departmentId));
                info.put("academicTitle", teacher.getAcademicTitle());
                info.put("phoneNumber", teacher.getPhoneNumber());
                return info;
            };
            List<Map<String, Object>> queryResult = queryResultStream.map(mapFunction).collect(Collectors.toList());
            result = JsonResultFactory.getInstance().buildSuccessResult(queryResult);
        }
        else {
            result = JsonResultFactory.getInstance().buildFailResult(ResultCode.PARAM_IS_BLANK);
        }
        return result;

    }

    /**
     * 新增教师的个人信息
     * 需要管理员权限
     */
    @PostMapping("/Teacher/AddInfo")
    @PreAuthorize("hasAuthority('admin')")
    public JsonResult addTeacherInfo(@RequestBody RequestTeacherDTO requestTeacherDTO) {

        JsonResult result = null;
        
        if (!requestTeacherDTO.checkParamValidity(true)) {
            result = JsonResultFactory.getInstance().buildFailResult(ResultCode.PARAM_FORMAT_ERROR);
        } 
        else {
            // 默认密码是和学号相同
            Teacher newTeacher =  requestTeacherDTO.toObjectTeacher();
            newTeacher.setPassword(new BCryptPasswordEncoder().encode(newTeacher.getTeacherId()));
            try {
                personManagementService.addTeacherInfo(newTeacher);
                result = JsonResultFactory.getInstance().buildSuccessResult("人员信息添加成功，默认密码与工号相同。");
            } catch (CustomException e) {
                result = JsonResultFactory.getInstance().buildFailResult(e.getResultCode());
            }
        } 
        
        return result;

    }

    /**
     * 删除教师的个人信息
     * 需要管理员权限
     */
    @PostMapping("/Teacher/DeleteInfo")
    @PreAuthorize("hasAuthority('admin')")
    public JsonResult deleteTeacherInfo(@RequestBody Map<String, String> params) {

        JsonResult result = null;
        JsonResultFactory jsonResultFactory = JsonResultFactory.getInstance();

        if(!ParamCheckingUtil.paramsNotEmpty(params, "teacherId")) {
            result = jsonResultFactory.buildFailResult(ResultCode.PARAM_NOT_COMPLETE);
        }
        else if (!ParamCheckingUtil.paramsNotEmpty(params, "teacherId")) {
            result = jsonResultFactory.buildFailResult(ResultCode.PARAM_IS_BLANK, "工号为空");
        } 
        else {
            try {
                personManagementService.deleteTeacher(params.get("teacherId"));
                result = jsonResultFactory.buildSuccessResult();
            }
            catch (CustomException e) {
                result = jsonResultFactory.buildFailResult(e.getResultCode());
            }
        }

        return result;

    }
}
